/**
* 开始节点只出不进
* 结束节点只进不出
* 业务节点多进多出，至少一入一出
**/


angular.module('com.dcos.app').directive("container",function($timeout){
  return{
    restrict: 'EA',
    scope: false,
    replace: true,
    templateUrl: '../../directive/flow/container.html',
    link:function(scope,element){
      
      var curLine=null;
      var startControl=null;
      var startNode="";  // 开始节点
      var endNode="";  // 结束节点
      var clickNode=null;
      scope.dragstatus =true; // true:移动模式 false:连线模式
      scope.curPlugin_Name="";
      var savedata={
        "p_id":"",
        "project_id":scope.curProjectId,
        "p_name":"",
        "description":"",
        "status":"1",
        "create_user":"",
        "trigger":"",
        "cycle":"",
        "node":[],
        "relation":[]
      };
      scope.savedata=savedata;
      
      scope.item=[
        { name: '删除' }
      ];
      scope.menuOptions = [
        ['删除', function ($itemScope) {
          if(clickNode){
            if(clickNode.type=="image"){
              var _arr=[];
              var _arrData=[];
              angular.forEach(connections,function(item,index){
                if(item.obj1.id==clickNode.id || item.obj2.id==clickNode.id) {
                  _arr.push(index);
                  _arrData.push(item.arrPath);
                }
              });
              angular.forEach(_arr.reverse(),function(item,index){
                connections.splice(item,1);
                _arrData[index].remove();
              });
              clickNode.data("cooperative").remove();
              clickNode.data("rect").remove();
            }
            else
            {
              angular.forEach(connections,function(item,index){
                if(item.arrPath.id==clickNode.id){
                  connections.splice(index,1);
                  return false;
                }
              });
            }
            clickNode.removeData();
            clickNode.remove();
            clickNode=null;
          }
        }]
      ];

      scope.fnInitData= function() {
        savedata.p_id=scope.flowdata.p_id;
        scope.p_name = scope.flowdata.p_name;
        scope.savedata.p_id=scope.flowdata.p_id;
        angular.forEach(scope.flowdata.node,function(item,index){
          var shape={
              "node_id":item.node_id,
              "pluginid":item.plugin_id,
              "plugintype":item.plugin_type,
              "node_type":item.node_type,
              "business_type":item.business_type,
              "image":{"src":item.icon_src,"x":parseInt(item.layerX),"y":parseInt(item.layerY),"width":32,"height":32},
              "text":{"content":item.plugin_name,"x":parseInt(item.layerX)+15,"y":parseInt(item.layerY)+40}
          }
          fnDrawShapes(shape,item);
 /*
          scope.formdata[item.node_id]={};
          scope.formdata[item.node_id].property=item.property;
          scope.formdata[item.node_id].nodeid=item.node_id;*/
        });
        /*
        $timeout(function() {
          scope.$apply();
        }, 0, false);

*/
        angular.forEach(scope.flowdata.relation,function (item,index) {
          var start_node=r.getById(item.start_nodeid);
          var end_node=r.getById(item.end_nodeid);
          connections.push(r.drawArr({ obj1: start_node, obj2: end_node }));
        });


        
      }
      //fnInitData();
      // 用来存储节点的顺序
      var connections = [];

      // 创建绘图对象
      var r = Raphael("holder", $("#holder").width()-20, $("#holder").height());


      /** region start 菜单按钮事件 **/
      // 点击菜单栏按钮，变更样式
      scope.fnchangeDragStatus = function (status) {
          scope.dragstatus = status;
          startControl=null;
          clickNode=null;
          curLine=null;
          if(status)
            $("#holder image").css("cursor","move");
          else
            $("#holder image").css("cursor","crosshair")
      }

      // 清空
      scope.fnClear = function () {
        scope.formdata = {};
        curLine=null;
        clickNode=null;
        startControl=null;
        r.clear();
      }

      var initLayoutX=1;

      // 保存
      scope.fnSaveFlow = function () {
        initLayoutX=1;
        var RealRelation=[];
        var branch=0;
        var _startNode=startNode;

        fnInitRelations();

        scope.savedata.node=[];
        
        fnRealRelation();  
       
        function fnRealRelation () {      
          angular.forEach(connections,function(item,index){
            if(!item.removed){
              if(item.obj1.id==_startNode || item.obj1.id==startNode) {
                if(item.obj1.id==startNode)
                  branch++;
                RealRelation.push({start_nodeid:item.obj1.id,end_nodeid:item.obj2.id});

                if(RealRelation.length==1){
                  scope.savedata.node.push(fnBuildNodeStructure(item.obj1,branch));
                  scope.savedata.node.push(fnBuildNodeStructure(item.obj2,branch));
                }
                else{
                  if(!fnValidateNodeExist(item.obj2.id))
                    scope.savedata.node.push(fnBuildNodeStructure(item.obj2,branch));
                }
                _startNode=item.obj2.id;
                item["removed"]=true;

                fnRealRelation();
              }
            }
          });
        }
        scope.savedata.relation=RealRelation;
        scope.fnSave(scope.savedata);
      }

      function fnInitRelations () {
        angular.forEach(connections,function(item,index){
          item["removed"]=false;
        });
      }

      function fnValidateNodeExist(node_id) {
        var result = false;
        angular.forEach(scope.savedata.node,function(item,index) {
          if(item.node_id==node_id) {
            result=true;
            return false;
          }
        });
        return result;
      }
      function fnGetComp (data) {

      }
      /** region end **/

      function fnBuildNodeStructure (data,branch) {
          var _node={};
          _node["plugin_id"] = data.plugin_id;
          _node["plugin_name"] = data.plugin_name;
          _node["node_id"] = data.id;
          _node["node_type"] = data.node_type;
          _node["business_type"] = data.business_type;
          _node["icon_src"] = data.attrs.src;

          _node["layerX"] = (initLayoutX*70).toString();//data.attrs.x.toString();
          _node["layerY"] = "60";
          initLayoutX++;
          _node["branch"] = branch;
          _node["plugin_type"] = data.plugin_type;
          
          var _property=[];
          angular.forEach(scope.vm.formdata[data.id].property,function(item,index) {
            var _data={};
            _data["property_name"]=item.property_name;
            _data["property_value"]=item.property_value;
            _data["property_lable"]=item.property_lable;
            if(data.plugin_name=="start" && item.property_name=="p_name")
              scope.savedata.p_name=item.property_value;
            _property.push(_data);
          });
          _node["property"]=_property;

          return _node;
      }/*
      function fnGetContainsNodeXY (nodeid) {
        r.getById(item)
      }*/
      Raphael.fn.drawArr = function (obj) {
          var point = getStartEnd(obj.obj1, obj.obj2);
          try{
              if (obj.arrPath) {
                  obj.arrPath.attr({ path: ["M", point.start.x, point.start.y, "L", point.end.x, point.end.y] });
              } else {
                  obj.arrPath = drawArrow(point.start.x, point.start.y, point.end.x, point.end.y);
              }
          }
          catch(err){}
          return obj;
      }

      // 验证节点是否可以连线
      function fnValidateNode (type,nodeid) {
        var result = true;
        angular.forEach(connections,function(item,index){
          if(item[type].id == nodeid) {
              result=false;
              return false;
          }
        });
        return result;
      }

      /** region start 节点事件  **/
      // 拖动节点开始时的事件
      var dragger = function () {
        if(scope.dragstatus) {
          this.ox = this.attr("x");
          this.oy = this.attr("y");
          this.animate({ "fill-opacity": .2 }, 500);
          if(curLine)
            curLine.remove();
        }
      };

      // 拖动事件
      var move = function (dx, dy) {
        if(scope.dragstatus) {
          var imageatt= { x: (this.ox + dx)<0?0:(this.ox + dx), y: (this.oy + dy)<0?0:(this.oy + dy) };
          var textatt = { x: (this.ox + dx)<0?15:(this.ox + dx + 15), y: (this.oy + dy)<0?40:(this.oy + dy + 40) };
          var rect ={x:(this.ox + dx)<0?0:(this.ox + dx-10),y:(this.oy + dy)<0?0:(this.oy + dy-10)}
          this.data("cooperative").attr(textatt);
          this.data("rect").attr(rect);
          this.attr(imageatt);
          for (var i = connections.length; i--; ) {
              r.drawArr(connections[i]);
          }
        }
      };

      // 拖动结束后的事件
      var up = function () {
        if(scope.dragstatus) {
          this.animate({ "fill-opacity": 0 }, 500);
        }
      };
      
      function fnclick(ev) {
        scope.curNodeId=this.id;
        scope.curPlugin_Name=" ( "+r.getById(this.id).plugin_name+" ) ";
        scope.$apply();
      }

      function fnMouseDown (ev) {
        clickNode=ev;
        if(fnValidateNode("obj1",ev.id)) {
          startControl = ev;
        } 
      }

      function fnMouseMove (ev) {

      }
      function fnMouseUp (ev) {
        if(fnValidateNode("obj2",ev.id)) {
          if(!scope.dragstatus &&　ev!=startControl &&　startControl){
            connections.push(r.drawArr({ obj1: startControl, obj2: ev }));
            startControl=null;
          }
        }
      }



      // 初始化节点
      function fnDrawShapes (shape,data) {
        var item = r.image(shape.image.src,shape.image.x,shape.image.y,shape.image.width,shape.image.height);
        var lable=r.text(shape.text.x, shape.text.y,  shape.text.content); 

        var border=r.rect(item.attrs.x-10, item.attrs.y-10, item.attrs.width+20, item.attrs.height+30, 5).attr({ stroke: "#000", "stroke-width": 1 }).hide();

        var color = Raphael.getColor();
        item.attr({ fill: color, stroke: color, "fill-opacity": 0, "stroke-width": 2, cursor: "move" });
        lable.attr({"font-size":"12px","fill":"#858B9D","opacity":1});
        item.id = shape.node_id;
        item.plugin_id=shape.pluginid;
        item.plugin_name=shape.text.content;
        item.node_type=shape.node_type;
        item.business_type=shape.business_type;
        item.plugin_type=shape.plugintype;
        item.drag(move, dragger, up).data("cooperative", lable).data("rect",border);
        item.click(fnclick);
        item.mousedown(function () {fnMouseDown(this)});
        item.mouseup(function () {fnMouseUp(this)});

        if(shape.text.content == "start")
          startNode=item.id;
        if(shape.text.content == "endNode")
          endNode=item.id;
          
        
        $timeout(function() {
          angular.forEach(scope.propertydata,function(a,b){
            if(a.plugin_id == shape.pluginid){
              if(a.property && data)
                angular.forEach(a.property,function(_a,_b){
                  _a["property_value"]=data.property[_b].property_value;
                });
              scope.vm.formdata[item.id]=angular.copy(a);
              scope.vm.formdata[item.id].nodeid=item.id;
              scope.$apply();
              return;
            }
          });
        }, 0, false);
        
      }


      /** region start 容器事件 **/
      $("#holder").bind("mouseup",function(ev) {
        if(!scope.dragstatus){
        	if(curLine!=null){
        		curLine.remove();
        	}
          startControl=null;
        }
      });
      $("#holder").bind("mousemove",function(ev){
        ev.preventDefault();
        if(!scope.dragstatus){
          if(startControl){
            if(curLine!=null)
              curLine.remove();
            if((ev.offsetX<startControl.attrs.x || ev.offsetX>startControl.attrs.x+32) || (ev.offsetY<startControl.attrs.y || ev.offsetY>startControl.attrs.y+32))
              curLine = drawArrow(startControl.attrs.x+30,startControl.attrs.y+30,ev.offsetX,ev.offsetY);
          }
        }
      });
      element[0].ondrop = function (ev) {
        if(scope.dragstatus) {
          ev.preventDefault();

          var data = ev.dataTransfer.getData("Text");
          var item = $("#" + data);
          var shape={
              "node_id":"node_"+guid(),
              "pluginid":item.attr("data-pluginid"),
              "plugintype":item.attr("data-plugintype"),
              "node_type":item.attr("data-nodetype"),
              "business_type":item.attr("data-businesstype"),
              "image":{"src":item.attr("data-imagesrc"),"x":ev.layerX,"y":ev.layerY,"width":32,"height":32},
              "text":{"content":item.attr("data-controlname"),"x":ev.layerX+15,"y":ev.layerY+40}
          }
          fnDrawShapes(shape,null);
          return true;
        }
      };
      element[0].ondragover = function (ev) {
        if(scope.dragstatus) {
          ev.preventDefault();
        }
      };

      function fnResizeContainer (container_id) {
        r.getById(container_id).attr({width:200,height:200});
        r.getById(container_id).data("rect").attr({width:200,height:200});
        /*
          var container=r.getElementsByPoint(container_id);
          var _widthIndex=container.data("plugins").length;
          var rect ={x:this.ox,y:this.oy,width:200,height:400}
          container.data("rect").attr(rect);*/
      }
      /** region end 容器事件 **/


      // 获取起点和终点坐标
      function getStartEnd(obj1, obj2) {
          var bb1 = obj1.getBBox(),
              bb2 = obj2.getBBox();
          var p = [
                  { x: bb1.x + bb1.width / 2, y: bb1.y - 1 },
                  { x: bb1.x + bb1.width / 2, y: bb1.y + bb1.height + 1 },
                  { x: bb1.x - 1, y: bb1.y + bb1.height / 2 },
                  { x: bb1.x + bb1.width + 1, y: bb1.y + bb1.height / 2 },
                  { x: bb2.x + bb2.width / 2, y: bb2.y - 1 },
                  { x: bb2.x + bb2.width / 2, y: bb2.y + bb2.height + 1 },
                  { x: bb2.x - 1, y: bb2.y + bb2.height / 2 },
                  { x: bb2.x + bb2.width + 1, y: bb2.y + bb2.height / 2 }
              ];
          var d = {}, dis = [];
          for (var i = 0; i < 4; i++) {
              for (var j = 4; j < 8; j++) {
                  var dx = Math.abs(p[i].x - p[j].x),
                      dy = Math.abs(p[i].y - p[j].y);
                  if (
                       (i == j - 4) ||
                       (((i != 3 && j != 6) || p[i].x < p[j].x) &&
                       ((i != 2 && j != 7) || p[i].x > p[j].x) &&
                       ((i != 0 && j != 5) || p[i].y > p[j].y) &&
                       ((i != 1 && j != 4) || p[i].y < p[j].y))
                     ) {
                      dis.push(dx + dy);
                      d[dis[dis.length - 1]] = [i, j];
                  }
              }
          }
          if (dis.length == 0) {
              var res = [0, 4];
          } else {
              res = d[Math.min.apply(Math, dis)];
          }
          var result = {};
          result.start = {};
          result.end = {};
          result.start.x = p[res[0]].x;
          result.start.y = p[res[0]].y;
          result.end.x = p[res[1]].x;
          result.end.y = p[res[1]].y;
          return result;
      }
      // 画连接线
      function drawArrow(x1, y1, x2, y2) {
      	var p = "M"+ x1 + " "+ y1 + "L" + x2 + " "+y2;
        var c = r.path(p).attr({
          'arrow-end' : 'classic-wide-long' ,
          'stroke': "#858B9D" ,
          "stroke-width" : 4
        }).mousedown(function(){fnMouseDown(this)});
        return c;
      }  


      /** region start 生成GUID **/
      function S4() {
         return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
      }
      function guid() {
         return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
      }
      /** region end 生成GUID **/
    }
  }
});
